Yes. The following template examples will work for all unsigned integers of length 1, 2, 4 and 8 bytes.
#include <type_traits> // for std::is_unsigned
template<class T>
T circular_shift_left( register T x )
{
static_assert( std::is_unsigned<T>::value, "circular_shift_left(T): T must be unsigned!\n" );
T bit = x;
switch( sizeof( x ))
{
case(1): bit &= (T) 0x80; break;
case(2): bit &= (T) 0x8000; break;
case(4): bit &= (T) 0x80000000; break;
case(8): bit &= (T) 0x8000000000000000; break;
default: assert( 0 );
}
x <<= 1;
x |= bit ? 1 : 0;
return( x );
}
template<class T>
T circular_shift_right( register T x )
{
static_assert( std::is_unsigned<T>::value, "circular_shift_right(T): T must be unsigned!\n" );
T bit = x & (T) 0x1;
switch( sizeof( x ))
{
case(1): bit = bit ? (T) 0x80 : 0x0; break;
case(2): bit = bit ? (T) 0x8000 : 0x0; break;
case(4): bit = bit ? (T) 0x80000000 : 0x0; break;
case(8): bit = bit ? (T) 0x8000000000000000 : 0x0; break;
default: assert( 0 );
}
x >>= 1;
x |= bit;
return( x );
}